package com.oisix.oisystemts2.service.autotask;

import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.mail.internet.InternetAddress;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.springframework.beans.factory.annotation.Required;

import com.google.gdata.util.common.net.UriEncoder;
import com.oisix.oisystemec.dao.KokyakuDao;
import com.oisix.oisystemec.exception.SystemException;
import com.oisix.oisystemec.model.AutoTaskHistory;
import com.oisix.oisystemec.service.autotask.AutoTask;
import com.oisix.oisystemec.service.autotask.AutoTaskDefinition;
import com.oisix.oisystemec.service.autotask.AutoTaskResult;
import com.oisix.oisystemec.service.autotask.AutoTaskStyle;
import com.oisix.oisystemec.service.autotask.ExecuteDecision;
import com.oisix.oisystemec.util.SiteCode;
import com.oisix.oisystemfr.persistence.EntityManager;
import com.oisix.oisystemfr.util.CsvWriter;

/**
 * CRO13: æœˆæœ«ãƒ�ã‚¤ãƒ³ãƒˆæ®‹é«˜ãƒªã‚¹ãƒˆä½œæˆ�.<br/>
 * Point balance auto task.
 * 
 * @author HungNM8
 * @since 2012/10/11
 * 
 */
public class PointBalanceService implements AutoTask {
    /** Output file name. */
    private static final String POINT_CSV = "pointo.csv";
    private static final String POINT_SUMMARY_CSV = "pointo_summary.csv";

    /** The type of auto task. */
    private String autoTaskType;
    /** The name of auto task. */
    private String autoTaskName;
    /** Company flag. */
    private int gochiFlg;

    /** Type of schedule. */
    private ExecuteDecision executeDecision;
    /** From email use to send auto task result mail. */
    private InternetAddress resultMailAddressFrom;
    /** To email use to send auto task result mail. */
    private List<InternetAddress> resultMailAddressTo;

    @Override
    public AutoTaskResult execute(AutoTaskHistory history, String user) {
        AutoTaskResult result;
        try {
            createPointBalanceFile();
            if (SiteCode.isOisixPureSiteCode()
                    || SiteCode.isGochimaruPureSiteCode()) {
                createPointSummaryFile();
            }

            result = new AutoTaskResult(true, "正常終了しました。");
        } catch (Exception e) {
            result = new AutoTaskResult(e);
        }
        return result;
    }

    private void createPointBalanceFile() {
        CsvWriter csvWriter = new CsvWriter(makepointFilename());
        csvWriter.setUseTextQualifier(true);
        List<Map<String, Object>> pointBalanceList = KokyakuDao.getPointBalance();
        int batchCount = 0;
        for (Map<String, Object> item : pointBalanceList) {
            batchCount++;
            String[] row = makeRow(item);
            csvWriter.writeRecord(row, false);
            if (batchCount == 200) {
                csvWriter.flush();
                batchCount = 0;
            }
        }
        csvWriter.flush();
        csvWriter.close();
    }

    private void createPointSummaryFile() {
        CsvWriter csvWriter = new CsvWriter(makesummarypointFilename());
        csvWriter.setUseTextQualifier(true);
        List<Map<String, Object>> pointBalanceList = KokyakuDao.getPointSummaryBalance();
        String[] row = makePointSummaryRow(pointBalanceList.get(0));
        csvWriter.writeRecord(row, false);
        csvWriter.flush();
        csvWriter.close();
    }

    /**
     * Create file pointo.csv.
     * 
     * @return String
     */
    public String makepointFilename() {
        StringBuilder sb = new StringBuilder();
        sb.append(createCsvFolder());
        sb.append(System.getProperty("file.separator"));
        sb.append(UriEncoder.encode(POINT_CSV));

        return sb.toString();
    }

    public String makesummarypointFilename() {
        StringBuilder sb = new StringBuilder();
        sb.append(createCsvFolder());
        sb.append(System.getProperty("file.separator"));
        sb.append(UriEncoder.encode(POINT_SUMMARY_CSV));

        return sb.toString();
    }

    /**
     * Create folder 'temp_file'.
     * 
     * @return String
     */
    public String createCsvFolder() {
        StringBuilder strDir = new StringBuilder();
        strDir.append(getFileFolderPath());
        strDir.append("temp_file");

        File f = new File(strDir.toString());
        if (!f.exists()) {
            if (!f.mkdirs()) {
                throw new SystemException("Unable to create directory " + f);
            }
        }

        return strDir.toString();
    }

    /**
     * Get path to pointo.csv file.
     * 
     * @return String
     */
    public String getFileFolderPath() {
        String path = System.getProperty("oisix.file.root");
        String separator = System.getProperty("file.separator");
        if (path != null && !path.endsWith("\\") && !path.endsWith("/")) {
            path += separator;
        }
        return path;
    }

    /**
     * Create csv rows item from each data record.
     * 
     * @return String[]
     */
    public String[] makeRow(Map<String, Object> item) {
        String kokyakuId = (String) item.get("kokyakuId");
        String shimei = (String) item.get("shimei");
        shimei = null == shimei ? shimei : shimei.replace(",", "");
        String furigana = (String) item.get("furigana");
        furigana = null == furigana ? furigana : furigana.replace(",", "");
        BigDecimal pointo = (BigDecimal) item.get("pointo");
        String point = null == pointo ? "0" : pointo.toPlainString();
        String shinkisakuseiDate = (String) item.get("shinkisakuseiDate");
        BigDecimal gochiFlg = (BigDecimal) item.get("gochiFlg");
        String siteCode = null == gochiFlg ? "0" : gochiFlg.toPlainString();

        String[] row = { kokyakuId, shimei, furigana, point, shinkisakuseiDate,
                siteCode };

        return row;
    }

    public String[] makePointSummaryRow(Map<String, Object> item) {
        // BigDecimal pointto = (BigDecimal) item.get("totalPoint");
        // String totalPoint = null == pointo ? "0" : pointo.toPlainString();

        BigDecimal pointo = (BigDecimal) item.get("totalPoint");
        String totalPoint = "0";
        if (pointo != null) {
            totalPoint = pointo.toPlainString();
        }

        String[] row = { totalPoint };
        return row;
    }

    @Override
    public String getAutoTaskName() {
        return autoTaskName;
    }

    @Required
    public void setAutoTaskName(String autoTaskName) {
        this.autoTaskName = autoTaskName;
    }

    @Override
    public String getAutoTaskType() {
        return autoTaskType;
    }

    @Required
    public void setAutoTaskType(String autoTaskType) {
        this.autoTaskType = autoTaskType;
    }

    @Override
    public String getDefinition() {
        return (new ReflectionToStringBuilder(this, new AutoTaskStyle()))
                .toString();
    }

    @Override
    public int getGochiFlg() {
        return gochiFlg;
    }

    @Required
    public void setGochiFlg(int gochiFlg) {
        this.gochiFlg = gochiFlg;
    }

    @Override
    public String getGochiFlgCaption() {
        return AutoTaskDefinition.getGochiFlgCaption(gochiFlg);
    }

    public ExecuteDecision getExecuteDecision() {
        return executeDecision;
    }

    @Required
    public void setExecuteDecision(ExecuteDecision executeDecision) {
        this.executeDecision = executeDecision;
    }

    @Override
    public String getTimingCaption() {
        return executeDecision.getTimingCaption();
    }

    @Override
    public boolean isExecutable(Date date) {
        return executeDecision.isExecutable(date);
    }

    @Override
    public InternetAddress getResultMailAddressFrom() {
        return resultMailAddressFrom;
    }

    @Required
    public void setResultMailAddressFrom(InternetAddress resultMailAddressFrom) {
        this.resultMailAddressFrom = resultMailAddressFrom;
    }

    @Override
    public List<InternetAddress> getResultMailAddressTo() {
        return resultMailAddressTo;
    }

    @Required
    public void setResultMailAddressTo(List<InternetAddress> resultMailAddressTo) {
        this.resultMailAddressTo = resultMailAddressTo;
    }

    @Override
    public void doBeforeCreateHistory(EntityManager em,
            AutoTaskHistory history, Timestamp taskDatehour, String user) {
    }
}
